package br.com.obardavez.util.impl;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import br.com.obardavez.util.DateUtil;
import br.com.obardavez.util.Util;

import com.google.inject.Inject;

public class DateUtilImpl implements DateUtil {

	private static final long serialVersionUID = 1L;

	private static final String DEFAULT_DATE_PATTERN = "dd/MM/yyyy";

	private static final String DEFAULT_DATE_TIME_PATTERN = "dd/MM/yyyy HH:mm:ss";
	
	private static final String SHORT_DATE_TIME_PATTERN = "dd/MM/yyyy HH:mm";

	@Inject
	private Util util;

	private String defaultDatePattern;

	private String defaultDatetimePattern;
	
	private String shortDateTimePattern;

	/* (non-Javadoc)
	 * @see com.digicade.android.util.impl.DateUtil#getDefaultDatePattern()
	 */
	@Override
	public String getDefaultDatePattern() {
		if (defaultDatePattern == null) {
			defaultDatePattern = DEFAULT_DATE_PATTERN;
		}
		return defaultDatePattern;
	}

	@Override
	public String getDefaultDatetimePattern() {
		if (defaultDatetimePattern == null) {
			defaultDatetimePattern = DEFAULT_DATE_TIME_PATTERN;
		}
		return defaultDatetimePattern;
	}
	
	@Override
	public String getShortDateTimePattern() {
		if (shortDateTimePattern == null) {
			shortDateTimePattern = SHORT_DATE_TIME_PATTERN;
		}
		return shortDateTimePattern;
	}
	
	/* (non-Javadoc)
	 * @see com.digicade.android.util.impl.DateUtil#setDefaultDatePattern(java.lang.String)
	 */
	@Override
	public void setDefaultDatePattern(String defaultDatePattern) {
		this.defaultDatePattern = defaultDatePattern;
	}

	/* (non-Javadoc)
	 * @see com.digicade.android.util.impl.DateUtil#format(java.util.Date)
	 */
	@Override
	public String format(Date date) {
		return format(date, getDefaultDatePattern());
	}

	/* (non-Javadoc)
	 * @see com.digicade.android.util.impl.DateUtil#format(java.util.Date, java.lang.String)
	 */
	@Override
	public String format(Date date, String format) {

		String formatedDate = "";
		if (date != null) {
			SimpleDateFormat sdf = new SimpleDateFormat(format);
			formatedDate = sdf.format(date);
		}

		return formatedDate;
	}

	/* (non-Javadoc)
	 * @see com.digicade.android.util.impl.DateUtil#parse(java.lang.String)
	 */
	@Override
	public Date parse(String date) {
		return parse(date, DEFAULT_DATE_PATTERN);
	}

	/* (non-Javadoc)
	 * @see com.digicade.android.util.impl.DateUtil#parse(java.lang.String, java.lang.String)
	 */
	@Override
	public Date parse(String date, String format) {

		Date parsedDate = null;

		if (util.getStringUtil().isNotEmpty(date)) {

			try {
				SimpleDateFormat sdf = new SimpleDateFormat(format);
				parsedDate = sdf.parse(date);
			} catch (ParseException e) {
				e.printStackTrace();
				throw new RuntimeException("Error parsing date.", e);
			}
		}

		return parsedDate;
	}

	/**
	 * Limpa os atributos referentes à hora
	 * 
	 * @param date
	 *            Data a ser alterada
	 * @return Data apenas com os campos referentes à dia, mês e ano preenchidos
	 */
	public Date clearTime(Date date) {

		Calendar cal = Calendar.getInstance();
		cal.setTime(date);

		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);

		return cal.getTime();
	}
	
	/* (non-Javadoc)
	 * @see com.digicade.android.util.impl.DateUtil#isValid(java.lang.String, java.lang.String)
	 */
	@Override
	public Boolean isValid(String data, String format) {

		try {
			DateFormat sdf = new SimpleDateFormat(format);
			sdf.setLenient(false);
			sdf.parse(data);
		} catch (Exception e) {
			return false;
		}

		return true;
	}
	
	@Override
	public long segundosEntre(Date data1, Date data2) {
		long segundosEntreDatas = 0;

		if (data1 != null && data2 != null) {
			segundosEntreDatas = Math.abs(data1.getTime() - data2.getTime()) / 1000;
		}

		return segundosEntreDatas;
	}
	
	/**
	 * Retorna o número de dias entre duas data e hora.
	 */
	public final long diasEntre(Date data1, Date data2) {
		return Math.round(Math.ceil(segundosEntre(data1, data2)/ (24 * 60 * 60.0)));
	}
	
	@Override
	public Date getDateAddDay(Date date, Integer daysToAdd) {

		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.DAY_OF_MONTH, daysToAdd);

		return cal.getTime();
	}
	
	@Override
	public Date getActualDateAddWeek(Integer weeksToAdd) {
		
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.WEEK_OF_MONTH, weeksToAdd);
		
		return cal.getTime();
	}
	
	@Override
	public Date getActualDateAddMonth(Integer monthsToAdd) {

		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.MONTH, monthsToAdd);

		return cal.getTime();
	}

}
